package com.sinosoft.generateDataInfo.system.service;

import java.io.File;
import java.io.FileFilter;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.dom4j.Element;

import com.sinosoft.generateDataInfo.common.xmlService.XmlReaderDom4j;
import com.sinosoft.generateDataInfo.system.dao.ISystemDao;
import com.sinosoft.generateDataInfo.system.vo.Table;

public class SystemServiceInOracleImpl implements ISystemService {
	
	
	private static final String FILE_FORLDER = XmlReaderDom4j.class.getClass().getResource("/").getPath();
	
	private static Logger logger = Logger.getLogger(SystemServiceInOracleImpl.class);
	
	private ISystemDao isystemDao;
	
	public ISystemDao getIsystemDao() {
		return isystemDao;
	}
	public void setIsystemDao(ISystemDao isystemDao) {
		this.isystemDao = isystemDao;
	}
	
	@Override
	public void create() {
		logger.info("==开始执行生产操作......" );
		createPRO_CREATE_TABLE();
		createTablesFromOpereateFile();
		logger.info("==结束执行生产操作......" );
	}
	
	@Override
	public void drop(){
		logger.info("==开始执行破坏操作......" );
		createPRO_DROP_TABLE();
		createPRO_DROP_PROCEDURE();
		dropTablesFromOpereateFile();
		dropPRO_CREATE_TABLE();
		dropPRO_DROP_TABLE();
		dropPRO_DROP_PROCEDURE();
		logger.info("==结束执行破坏操作......" );
	}
	
	@Override
	public void initData() {
		logger.info("==开始执行数据写入操作......" );
		final File[] operateFiles = getOperateFiles();
		for(int i=0;i<operateFiles.length;i++){
			logger.info("------"+(i+1)+"......" );
			logger.info("--------文件 ["+operateFiles[i].getName()+"]开始读取操作......" );
			List<Table> datas = getOperateFileTables(operateFiles[i], "//tables/table/initData");
			logger.info("--------文件 ["+operateFiles[i].getName()+"]共有数据["+datas.size()+"]即将进行写入......" );
			for(int j=0;j<datas.size();j++){
				Table t = datas.get(j);
				try{
					isystemDao.operate(t.getTableCode().replaceAll("''", "'"));
					logger.info("------------数据 ["+t.getTableCode().replaceAll("''", "'")+"] 写入成功......" );
				}catch (SQLException e) {
					logger.error("------------数据  ["+t.getTableCode().replaceAll("''", "'")+"] 写入失败......" );
					e.printStackTrace();
				}
			}
			logger.info("--------文件 ["+operateFiles[i].getName()+"]结束读取操作......" );
		}
		logger.info("==结束执行数据写入操作......" );
	}
	
	private void createTablesFromOpereateFile(){
		final File[] operateFiles = getOperateFiles();
		for(int i=0;i<operateFiles.length;i++){
			logger.info("------"+(i+1)+"......" );
			logger.info("--------文件 ["+operateFiles[i].getName()+"]开始读取操作......" );
			List<Table> tables = getOperateFileTables(operateFiles[i], "//tables/table");
			logger.info("--------文件 ["+operateFiles[i].getName()+"]共有表格["+tables.size()+"]个表格进行写入......" );
			for(int j=0;j<tables.size();j++){
				Table t = tables.get(j);
				try{
					isystemDao.createTable(t);
					logger.info("------------表格 ["+t.getTableName()+"] 写入成功......" );
				}catch (SQLException e) {
					logger.error("------------表格 ["+t.getTableName()+"] 写入失败......" );
					e.printStackTrace();
				}
			}
			
			if("Tables_system.xml".equals(operateFiles[i].getName())){
				logger.info("------------******执行系统管理插入xml，特殊执行次内容...开始..." );
				createPRO_REGISTER_LOGOUT_STATUS();
				createPRO_REGISTER_LOGOUT_STATUS_IntervalRun();
				logger.info("------------******执行系统管理插入xml，特殊执行次内容...结束..." );
			}

			logger.info("--------文件 ["+operateFiles[i].getName()+"]结束读取操作......" );
		}
	}
	
	private void dropTablesFromOpereateFile(){
		final File[] operateFiles = getOperateFiles();
		for(int i=0;i<operateFiles.length;i++){
			logger.info("------"+(i+1)+"......" );
			logger.info("--------文件 ["+operateFiles[i].getName()+"]开始读取操作......" );
			List<Table> tables = getOperateFileTables(operateFiles[i], "//tables/table");
			logger.info("--------文件 ["+operateFiles[i].getName()+"]共有表格["+tables.size()+"]个表格进行删除......" );
			for(int j=0;j<tables.size();j++){
				Table t = tables.get(j);
				try{
					isystemDao.dropTable(t);
					logger.info("------------表格 ["+t.getTableName()+"] 删除成功......" );
				}catch (SQLException e) {
					logger.error("------------表格 ["+t.getTableName()+"] 删除失败......" );
					e.printStackTrace();
				}
			}
			
			if("Tables_system.xml".equals(operateFiles[i].getName())){
				logger.info("------------******执行系统管理插入xml，特殊执行次内容...开始..." );
				dropPRO_REGISTER_LOGOUT_STATUS();
				dropPRO_REGISTER_LOGOUT_STATUS_IntervalRun();
				logger.info("------------******执行系统管理插入xml，特殊执行次内容...结束..." );
			}

			logger.info("--------文件 ["+operateFiles[i].getName()+"]结束读取操作......" );
		}
	}
	
	
	private List<Table> getOperateFileTables(File operateFile , String xpathForLabel){
		List<Table> tables = null;
		try {
			tables = elementsTurnToTables(XmlReaderDom4j.readerXMLFileByXpathReturnElements(operateFile, xpathForLabel));
		} catch (DocumentException e) {
			logger.error("--------文件 ["+operateFile.getName()+"]读取结构失败，请检查此文件内容的正确性......" );
			e.printStackTrace();
		}
		return (tables==null?new ArrayList<Table>():tables);
		
	}
	
	
	private File[] getOperateFiles(){
		logger.info("----开始获取执行需要操作的文件夹中的文件......" );
		final File operateDirectory = new File(SystemServiceInOracleImpl.FILE_FORLDER);
		if(!operateDirectory.isDirectory())operateDirectory.mkdir();
		final File[] operateFiles = operateDirectory.listFiles(new FileFilter() {
			@Override
			public boolean accept(File file) {
				return file.getName().startsWith("Tables") && file.getName().endsWith(".xml");
			}
		});
		logger.info("----已获取执行文件 ["+operateFiles.length+"]个......" );
		return operateFiles;  
	}
	
	private List<Table> elementsTurnToTables(List<Element> elements){
		List<Table> tables = null;
		for (Iterator<Element> iter = elements.iterator(); iter.hasNext(); ) {
			Element e = iter.next();
			if(tables == null)tables = new ArrayList<Table>();
			Table ta = new Table();
			ta.setTableCode(e.getText().replaceAll("'", "''"));
			ta.setTableName(e.attributeValue("id"));
			tables.add(ta);
        }
		return tables;
	}
	
	private void createPRO_CREATE_TABLE(){
		logger.info("----创建用于建表的存储过程......开始......" );
		try {
			isystemDao.createPRO_CREATE_TABLE();
			logger.info("----创建用于建表的存储过程......成功......" );
		} catch (SQLException e) {
			logger.error("----创建用于建表的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}

	private void dropPRO_CREATE_TABLE(){
		logger.info("----删除用于建表的存储过程......开始......" );
		try {
			isystemDao.dropPRO_CREATE_TABLE();
			logger.info("----删除用于建表的存储过程......成功......" );
		} catch (Exception e) {
			logger.error("----删除用于建表的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}

	private void createPRO_REGISTER_LOGOUT_STATUS(){
		logger.info("----创建用于系统管理用户注销的存储过程......开始......" );
		try {
			isystemDao.createPRO_REGISTER_LOGOUT_STATUS();
			logger.info("----创建用于系统管理用户注销的存储过程......成功......" );
		} catch (SQLException e) {
			logger.error("----创建用于系统管理用户注销的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}	
	
	private void createPRO_REGISTER_LOGOUT_STATUS_IntervalRun(){
		logger.info("----创建用于系统管理用户注销的管理job内容......开始......" );
		try {
			isystemDao.createPRO_REGISTER_LOGOUT_STATUS_IntervalRun();
			logger.info("----创建用于系统管理用户注销的管理job内容......成功......" );
		} catch (SQLException e) {
			logger.error("----创建用于系统管理用户注销的管理job内容......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}
	
	private void createPRO_DROP_TABLE(){
		logger.info("----创建用于删除表的存储过程......开始......" );
		try {
			isystemDao.createPRO_DROP_TABLE();
			logger.info("----创建用于删除表的存储过程......成功......" );
		} catch (SQLException e) {
			logger.error("----创建用于删除表的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}
	private void createPRO_DROP_PROCEDURE(){
		logger.info("----创建用于删除存储过程的存储过程......开始......" );
		try {
			isystemDao.createPRO_DROP_PROCEDURE();
			logger.info("----创建用于删除存储过程的存储过程......成功......" );
		} catch (SQLException e) {
			logger.error("----创建用于删除存储过程的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}
	
	private void dropPRO_REGISTER_LOGOUT_STATUS_IntervalRun(){
		logger.info("----删除用于系统管理用户注销的管理job内容......开始......" );
		try {
			isystemDao.dropPRO_REGISTER_LOGOUT_STATUS_IntervalRun();
			logger.info("----删除用于系统管理用户注销的管理job内容......成功......" );
		} catch (SQLException e) {
			logger.error("----删除用于系统管理用户注销的管理job内容......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}	

	private void dropPRO_REGISTER_LOGOUT_STATUS(){
		logger.info("----删除用于系统管理用户注销的存储过程......开始......" );
		try {
			isystemDao.dropPRO_REGISTER_LOGOUT_STATUS();
			logger.info("----删除用于系统管理用户注销的存储过程......成功......" );
		} catch (SQLException e) {
			logger.error("----删除用于系统管理用户注销的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}
	
	private void dropPRO_DROP_TABLE(){
		logger.info("----删除用于删除表的存储过程......开始......" );
		try {
			isystemDao.dropPRO_DROP_TABLE();
			logger.info("----删除用于删除表的存储过程......成功......" );
		} catch (SQLException e) {
			logger.error("----删除用于删除表的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}	

	private void dropPRO_DROP_PROCEDURE(){
		logger.info("----删除用于删除存储过程的存储过程......开始......" );
		try {
			isystemDao.dropPRO_DROP_PROCEDURE();
			logger.info("----删除用于删除存储过程的存储过程......成功......" );
		} catch (SQLException e) {
			logger.error("----删除用于删除存储过程的存储过程......失败.原因["+e.getMessage()+"]......" );
			e.printStackTrace();
		}
	}	
}
